#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cre2.h>

#define PRINTF(...) { printf(__VA_ARGS__);         fflush(stdout); }
#define FWRITE(...) { fwrite(__VA_ARGS__, stdout); fflush(stdout); }

int main (void)
{
    { /* 成功匹配，无括号分组 */
        const char *pattern = "ci.*ut";
        const char *text = "pre ciao salut post";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int result;

        result = cre2_partial_match(pattern, &input, NULL, 0);
        PRINTF("no paren ret = %d\n", result);

        if (!result)
            goto error;
    }
    { /* 匹配成功，一个括号分组，一个匹配项 */
        const char *pattern = "(ciao) salut";
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 1;
        cre2_string_t match[nmatch];
        int result;

        result = cre2_partial_match(pattern, &input, match, nmatch);
        PRINTF("one paren one match ret = %d\n", result);

        if (!result)
            goto error;

        // match[0]表示第一个分组
        PRINTF("match 0: ");
        FWRITE(match[0].data, match[0].length, 1);
        PRINTF("\n");
    }
    { /* 匹配成功，两个括号分组，两个匹配项 */
        const char *pattern = "(ciao) (salut)";
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 2;
        cre2_string_t match[nmatch];
        int result;

        result = cre2_partial_match(pattern, &input, match, nmatch);
        PRINTF("two parens two matchs ret = %d\n", result);

        if (!result)
            goto error;

        // match[0]表示第一个分组
        PRINTF("match 0: ");
        FWRITE(match[0].data, match[0].length, 1);
        PRINTF("\n");
        PRINTF("match 1: ");
        FWRITE(match[1].data, match[1].length, 1);
        PRINTF("\n");
    }
    { /* 匹配失败，无括号分组 */
        const char *pattern = "ci.*ut";
        const char *text = "ciao hello";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int result;

        result = cre2_partial_match(pattern, &input, NULL, 0);
        PRINTF("failure no paren ret = %d\n", result);

        if (result)
            goto error;
    }
    { /* 匹配失败，一个括号分组 */
        const char *pattern = "(ciao) salut";
        const char *text = "ciao hello";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 1;
        cre2_string_t match[nmatch];
        int result;

        result = cre2_partial_match(pattern, &input, match, nmatch);
        PRINTF("failure one paren ret = %d\n", result);

        if (result)
            goto error;
    }
    { /* 匹配成功，一个括号分组，无匹配项 */
        const char *pattern = "(ciao) salut";
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int result;

        result = cre2_partial_match(pattern, &input, NULL, 0);
        PRINTF("one paren zero match ret = %d\n", result);

        if (!result)
            goto error;
    }
    { /* 匹配失败，一个括号分组，两个匹配项 */
        const char *pattern = "(ciao) salut";
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 2;
        cre2_string_t match[nmatch];
        int result;

        memset(match, '\0', nmatch * sizeof(cre2_string_t));

        result = cre2_partial_match(pattern, &input, match, nmatch);
        PRINTF("failure, one paren two matchs ret = %d\n", result);

        if (0 != result)
            goto error;
    }
    { /* 匹配成功，两个括号分组，一个匹配项 */
        const char *pattern = "(ciao) (salut)";
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 1;
        cre2_string_t match[nmatch];
        int result;

        result = cre2_partial_match(pattern, &input, match, nmatch);
        PRINTF("two parens one match ret = %d\n", result);

        if (!result)
            goto error;

        // match[0]表示第一个分组
        PRINTF("match 0: ");
        FWRITE(match[0].data, match[0].length, 1);
        PRINTF("\n");
    }
    { /* 正则表达式错误 */
        const char *pattern = "cia(o salut";
        const char *text = "ciao hello";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 1;
        cre2_string_t match[nmatch];
        int result;

        // 自动输出日志
        result = cre2_partial_match(pattern, &input, match, nmatch);
        PRINTF("regexp error = %d\n", result);

        if (0 != result)
            goto error;
    }

    { /* 匹配成功，无括号分组 */
        const char *pattern = "ci.*ut";
        cre2_regexp_t *rex;
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int result;

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, NULL, 0);
        PRINTF("rex no paren no match ret = %d\n", result);

        cre2_delete(rex);
        if (!result)
            goto error;
    }
    { /* 匹配成功，一个括号分组，一个匹配项 */
        const char *pattern = "(ciao) salut";
        cre2_regexp_t *rex;
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 1;
        cre2_string_t match[nmatch];
        int result;

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, match, nmatch);
        PRINTF("rex one paren one match ret = %d\n", result);

        cre2_delete(rex);
        if (!result)
            goto error;

        // match[0]表示第一个分组
        PRINTF("match 0: ");
        FWRITE(match[0].data, match[0].length, 1);
        PRINTF("\n");
    }
    { /* 匹配成功，两个括号分组，两匹配项 */
        const char *pattern = "(ciao) (salut)";
        cre2_regexp_t *rex;
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 2;
        cre2_string_t match[nmatch];
        int result;

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, match, nmatch);
        PRINTF("rex two parens two matchs ret = %d\n", result);

        cre2_delete(rex);
        if (!result)
            goto error;

        // match[0]表示第一个分组
        PRINTF("match 0: ");
        FWRITE(match[0].data, match[0].length, 1);
        PRINTF("\n");
        PRINTF("match 1: ");
        FWRITE(match[1].data, match[1].length, 1);
        PRINTF("\n");
    }
    { /* 匹配失败，无括号分组 */
        const char *pattern = "ci.*ut";
        cre2_regexp_t *rex;
        const char *text = "ciao hello";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int result;

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, NULL, 0);
        PRINTF("rex failure no paren ret = %d\n", result);

        cre2_delete(rex);
        if (result)
            goto error;
    }
    { /* 匹配失败，一个括号分组 */
        const char *pattern = "(ciao) salut";
        cre2_regexp_t *rex;
        const char *text = "ciao hello";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 1;
        cre2_string_t match[nmatch];
        int result;

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, match, nmatch);
        PRINTF("rex failure one paren ret = %d\n", result);

        cre2_delete(rex);
        if (result)
            goto error;
    }
    { /* 匹配成功，一个括号分组，无匹配项 */
        const char *pattern = "(ciao) salut";
        cre2_regexp_t *rex;
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int result;

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, NULL, 0);
        PRINTF("rex one paren no match ret = %d\n", result);

        cre2_delete(rex);
        if (!result)
            goto error;
    }
    { /* 匹配失败，一个括号分组，两个匹配项 */
        const char *pattern = "(ciao) salut";
        cre2_regexp_t *rex;
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 2;
        cre2_string_t match[nmatch];
        int result;

        memset(match, '\0', nmatch * sizeof(cre2_string_t));

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, match, nmatch);
        PRINTF("rex failure one paren two matchs ret = %d\n", result);

        cre2_delete(rex);
        if (0 != result)
            goto error;
    }
    { /* 匹配成功，两个括号分组，一个匹配项 */
        const char *pattern = "(ciao) (salut)";
        cre2_regexp_t *rex;
        const char *text = "ciao salut";
        cre2_string_t input = { .data = text, .length = strlen(text) };
        int nmatch = 1;
        cre2_string_t match[nmatch];
        int result;

        rex = cre2_new(pattern, strlen(pattern), NULL);

        result = cre2_partial_match_re(rex, &input, match, nmatch);
        PRINTF("rex two parens one matchs ret = %d\n", result);

        cre2_delete(rex);
        if (!result)
            goto error;

        // match[0]表示第一个分组
        PRINTF("match 0: ");
        FWRITE(match[0].data, match[0].length, 1);
        PRINTF("\n");
    }

    exit(EXIT_SUCCESS);
error:
    exit(EXIT_FAILURE);
}
